package com.xjc.infra.util;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.xjc.infra.base.BaseErrorCodes;
import com.xjc.infra.entity.SessionContext;
import com.xjc.infra.exception.IFSException;



/**
 * SessionContext工具类
 * @class com.ifs.infra.tools.SessionContextUtil
 *
 * @date 2016年6月17日
 * @author lqf
 *
 */
@Service
public class SessionContextUtil {

	private String entityCode;
	private String serviceCode;
	private String transactionBranch;
	private String format = "yyyy-MM-dd HH:mm:ss SSS";
	private static final ThreadLocal<SessionContext> LOCAL_SESSIONCONTEXT = new ThreadLocal<SessionContext>();

	private MessageSourceUtil messageSourceUtil;
	
	public SessionContextUtil(){
		entityCode = SystemGlobals.getProperty("entityCode");
		serviceCode = SystemGlobals.getProperty("serviceCode");
		transactionBranch = SystemGlobals.getProperty("transactionBranch");
	}
	
	/**
	 * 创建默认sessionContext
	 * @return
	 * @date 2016年6月17日
	 * @throws IFSException entityCode/serviceCode/transactionBranch 为空时向外抛出异常抛异常
	 * @author lqf
	 */
	public  SessionContext createSessionContext() throws IFSException{
		if(null==entityCode || StringUtils.isBlank(serviceCode) || StringUtils.isBlank(transactionBranch)){
			throw new IFSException(new Exception("entityCode is null or serviceCode is null or transactionBranch is null"), 
					String.valueOf(BaseErrorCodes.BASE_TX_PARAM_NULL),
					messageSourceUtil.expandErrMsg(String.valueOf(BaseErrorCodes.BASE_TX_PARAM_NULL)));
		}
		try {
			Integer.parseInt(entityCode);
		} catch (Exception e) {
			throw new IFSException(new Exception("entityCode must be number"), 
					String.valueOf(BaseErrorCodes.BASE_TX_PARAM_SYSERROR),
					messageSourceUtil.expandErrMsg(String.valueOf(BaseErrorCodes.BASE_TX_PARAM_SYSERROR)));
		}
		SessionContext sessionContext = new SessionContext();
		sessionContext.setEntityCode(Integer.parseInt(entityCode));
		sessionContext.setServiceCode(serviceCode);
		sessionContext.setTransactionBranch(transactionBranch);
		sessionContext.setUserReferenceNumber(ReferenceNoUtils.createSysDefaultReferenceNo());
		sessionContext.setExternalReferenceNo(ReferenceNoUtils.createSysDefaultReferenceNo());
		sessionContext.setPostingDateText(new SimpleDateFormat(format).format(new Date()));
		if(serviceCode.toLowerCase().contains("portal")){
			sessionContext.setChannel("WEB");
		}else if(serviceCode.toLowerCase().contains("h5api")){
			sessionContext.setChannel("MOBILE");
		}
		return sessionContext;
	}
	
	/**
	 * 创建sessionContext
	 * @param channel
	 * @param remoteIp
	 * @param customerId
	 * @param customerType
	 * @param customerValidationStatus
	 * @param customerLimit
	 * @param accessSource
	 * @param accessSourceType
	 * @return
	 * @date 2016年6月17日
	 * @author lqf
	 */
	public  SessionContext createSessionContext(String channel,String remoteIp,
			String customerId,String customerType,String customerValidationStatus,
			String customerLimit,String accessSource,String accessSourceType){
		SessionContext sessionContext = createSessionContext();
		sessionContext.setChannel(channel);
		sessionContext.setRemoteIp(remoteIp);
		sessionContext.setCustomerId(customerId);
		sessionContext.setCustomerType(customerType);
		sessionContext.setCustomerValidationStatus(customerValidationStatus);
		sessionContext.setCustomerLimit(customerLimit);
		sessionContext.setAccessSource(accessSourceType);
		sessionContext.setAccessSourceType(accessSourceType);
		return sessionContext;
	}
	
	/**
	 * 根据HttpServletRequest 设置sessionContext其他属性值
	 * @param request
	 * @param sessionContext
	 * @return
	 * @date 2016年6月22日
	 * @author lqf
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public  SessionContext fillSessionContext(SessionContext sessionContext){
		HttpServletRequest request = HttpServletRequestUtil.getHttpServletRequest();
		if(null== request  || null==sessionContext){
			return sessionContext;
		}
		//设置 访问源信息
		sessionContext.setRemoteIp(HttpServletRequestUtil.getRequestIP(request));
		sessionContext.setAccessSource(HttpServletRequestUtil.getAccessSouce(request));//系统访问源，电脑、IOS、Andrion
		sessionContext.setAccessSourceType(HttpServletRequestUtil.getBrowserType(request));//访问源类型即浏览器类型
		//用户未登录
		if( null== request.getSession() || null==request.getSession().getAttribute("users")){
			sessionContext.setCustomerId("guest");//系统访问者客户ID，如果未登陆则默认为“guest”。	
			return sessionContext;
		}
		
		Object csDTO =  (Object)request.getSession().getAttribute("users");			
		try {
			Class clazz = csDTO.getClass(); 
			Method m1 = clazz.getDeclaredMethod("getCodCustCode");
			Method m2 = clazz.getDeclaredMethod("getCodCustType");
			Method m3 = clazz.getDeclaredMethod("getCodCustCrStatus");
			Method m4 = clazz.getDeclaredMethod("getCodCustBusLimit");
			
			sessionContext.setCustomerId((String)m1.invoke(csDTO));//系统访问者客户ID，如果未登陆则默认为“guest”。
			sessionContext.setCustomerType((String)m2.invoke(csDTO));// 系统访问者客户类型，如果未登陆则默认为空。
			sessionContext.setCustomerValidationStatus((String)m3.invoke(csDTO));//系统访问者认证位状态，如果未登陆为空。
			sessionContext.setCustomerLimit((String)m4.invoke(csDTO));//系统客户权限位，系统暂保留，可为空。
		} catch (Exception e) {
			sessionContext.setCustomerId(null);//出错时设为空
		}
		return sessionContext;
	}
	
	public MessageSourceUtil getMessageSourceUtil() {
		return messageSourceUtil;
	}

	public void setMessageSourceUtil(MessageSourceUtil messageSourceUtil) {
		this.messageSourceUtil = messageSourceUtil;
	}
	/**
	 * 获取当前线程的sessiontext
	 * @author liangcz
	 * @date   2017年12月7日 下午2:36:49
	 * @return SessionContext
	 */
	public static SessionContext getLocalSessionContext(){
		SessionContext sessionContext = LOCAL_SESSIONCONTEXT.get();
		return sessionContext;
	}
	/**
	 * 更新当前线程sessiontext
	 * @author liangcz
	 * @date   2017年12月7日 下午2:37:05
	 * @return void
	 */
	public static void setLocalSessionContext(SessionContext sessionContext){
		LOCAL_SESSIONCONTEXT.set(sessionContext);
	}
	/**
	 * 清空当前线程sessiontext
	 * @author liangcz
	 * @date   2017年12月7日 下午2:37:40
	 * @return void
	 */
	public static void clearLocalSessionContext() {
		LOCAL_SESSIONCONTEXT.remove();
	}
}
